home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / interapplication comm / folder watching / folder watcher fba / fba.c next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  6.9 KB  |  292 lines

  1. /*
  2.     File:        FBA.c
  3.  
  4.     Contains:    
  5.  
  6.     Written by: Greg Sutton    
  7.  
  8.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/21/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24.     // Includes
  25. #include "FBA.h"
  26. #include "FBAAppleEvents.h"
  27. #include "FBATask.h"
  28. #include "FBALists.h"
  29.  
  30. #include <Gestalt.h>
  31. #include <LowMem.h>
  32. #include <Events.h>
  33. #include <Notification.h>
  34. #include <Resources.h>
  35.  
  36. #ifdef DEVELOPMENT
  37.     #include <TextEdit.h>
  38.     #include <Dialogs.h>
  39. #endif
  40.  
  41.  
  42.     // Prototypes
  43. static void             IncreaseFBAStack(Size extraBytes);
  44. static Boolean            HasFullExtFSDispatching( void );
  45. static Boolean            HasProcessManager( void );
  46. static void                InitCycleTime( void );
  47. static unsigned long    GetResourceCycleTime( void );
  48.  
  49. static void                CheckEventQueue( void );
  50.  
  51. static void                Notify( StringPtr notice, Boolean fFatal );
  52.  
  53. static pascal void        MyResponse( NMRecPtr n );
  54.  
  55.  
  56.     // Globals
  57. #if !defined(THINK_C) && !defined(__MWERKS__)
  58.         QDGlobals       qd;
  59. #endif
  60.  
  61. short             gQuit = false;
  62. unsigned long    gCycleTime;            // Time requested to check all folders
  63.  
  64.     // Constants
  65. const unsigned long    DefaultCycleTime = 30;    // Default cycle time for all folders
  66.                                             // to be checked in seconds.
  67. const short            StackSize = 32;            // Default stack size for an FBA is 2K
  68.                                             // Set StackSize to the K wanted.
  69.  
  70.  
  71. void    main( void )
  72. {
  73.     Boolean            fQuit;
  74.     
  75.     IncreaseFBAStack(StackSize * 1024);
  76.  
  77.     MaxApplZone();
  78.     
  79.     InitGraf( &qd.thePort );    // Always call InitGraf; otherwise,
  80.                                 // AppleEvents, Random(), and other calls won't work.
  81.  
  82. #ifdef DEVELOPMENT    // See 'FBA.h' for #define
  83.     InitFonts( );
  84.     InitWindows( );
  85.     InitMenus( );
  86.     TEInit( );
  87.     InitDialogs( 0L );
  88.     InitCursor( );
  89. #endif
  90.  
  91.     if ( noErr != InitAppleEvents( ) )
  92.         Notify( "\pFolder Watcher failed to initialize Apple events", kFatalErr );
  93.     
  94.     if ( ! HasFullExtFSDispatching( ) )
  95.         Notify( "\pFolder Watcher failed due to limited CatSearch", kFatalErr );
  96.     
  97.     if ( ! HasProcessManager( ) )
  98.         Notify( "\pFolder Watcher failed due to no Process Manager", kFatalErr );
  99.         
  100.     if ( ! InitTask( ) )
  101.         Notify( "\pFolder Watcher failed due to bad task initialization", kFatalErr );
  102.  
  103.     InitWatchFolders( );
  104.     InitCycleTime( );
  105.     
  106.     fQuit = gQuit;                        // Initialization may set gQuit to true
  107.     
  108.     while ( ! fQuit )
  109.     {
  110.         CheckEventQueue( );
  111.         
  112.         if ( gQuit )                    // We want to quit
  113.             fQuit = CanQuitTask( );        // Check that our task can quit now
  114.     }
  115. }
  116.  
  117. // Increase the space allocated for the background only application
  118. // stack.
  119. // 
  120. // Call this routine before calling MaxApplZone, during program
  121. // initialization.
  122. // 
  123. // Warning: 
  124. //     SetApplLimit always sets the stack to at least as large as the
  125. //     default stack for the machine (8K on machines with original
  126. //     QuickDraw, 24K on machines with Color QuickDraw), so the
  127. //     application partition must be large enough to accommodate an
  128. //     appropriate stack and heap.
  129. // 
  130. // Call this only once, at the beginning of the background only
  131. // application.
  132. // 
  133. // Another warning: 
  134. //     Don't bother trying to set the stack size to something lower
  135. //     than 24K. If SetApplLimit is called to do this, it will
  136. //     silently lower ApplLimit to a 24K stack.
  137.  
  138. static void IncreaseFBAStack(Size extraBytes)
  139. {
  140.     THz        myZone;
  141.     SysEnvRec    sys;
  142.  
  143.     SysEnvirons(1, &sys);
  144.  
  145.     if (sys.systemVersion < 0x0755)
  146.     {
  147.         // Check that we aren't running with a corrupt heap. If we are,
  148.         // fix the problem.  This was a bug with FBA's before System 7.5.5.  
  149.         myZone = GetZone();
  150.         if (myZone->bkLim != LMGetHeapEnd())
  151.             LMSetHeapEnd(myZone->bkLim);
  152.     }
  153.     // Increase the stack size by lowering the heap limit.
  154.     SetApplLimit((Ptr) ((Size) GetApplLimit() - extraBytes));
  155. }
  156.  
  157.  
  158. static void    CheckEventQueue( void )
  159. {
  160.     long                    sleepTicks = 1;    // First time through return from
  161.                                             //  WaitNextEvent() as quick as possible.
  162.     EventRecord             anEvent;
  163.     OSErr                    err;
  164.  
  165.     WaitNextEvent( highLevelEventMask, &anEvent, sleepTicks, NULL );
  166.     
  167.     switch ( anEvent.what )
  168.     {
  169.         case kHighLevelEvent :
  170.             err = DoAppleEvent( &anEvent );
  171.         break;
  172.     }
  173.     
  174.         // Call background task no matter if event
  175.         //  is a high level or null event.
  176.     sleepTicks = DoBackgroundTask( );        // Do our background task or return
  177.                                             //  an updated sleep time.
  178. }
  179.  
  180.  
  181. // See if File Manager will pass CatSearch requests to external file systems.
  182.  
  183. static Boolean    HasFullExtFSDispatching( void )
  184. {
  185.     long        response;
  186.     Boolean        result = false;
  187.  
  188.     if ( noErr == Gestalt( gestaltFSAttr, &response ) )
  189.         result = ((response & (1L << gestaltFullExtFSDispatching)) != 0);
  190.         
  191.     return result;
  192. }
  193.  
  194.  
  195. // Check that we have the process manager
  196.  
  197. static Boolean    HasProcessManager( void )
  198. {
  199.     long        response;
  200.     Boolean        result = false;
  201.  
  202.     if ( noErr == Gestalt( gestaltOSAttr, &response ) )
  203.         result = true;
  204.         
  205.     return result;
  206. }
  207.  
  208.  
  209. static void    InitCycleTime( void )
  210. {
  211.     gCycleTime = GetResourceCycleTime();
  212. }
  213.  
  214.  
  215. unsigned long    GetCycleTime( void )
  216. {
  217.     return gCycleTime;
  218. }
  219.  
  220.  
  221. // If there are 'Cycl' resources then use the first of these for the sleep time.
  222. // Otherwise use the default cycle time. The time is supposed to be in seconds.
  223.  
  224. static unsigned long GetResourceCycleTime( void )
  225. {
  226.     short            count;
  227.     Handle             aHandle;
  228.     unsigned long    result = DefaultCycleTime;
  229.     
  230.     count = Count1Resources( kCycleTimeResource );
  231.     if ( count )
  232.     {
  233.         aHandle = Get1IndResource( kCycleTimeResource, 1 );
  234.         if ( aHandle )
  235.         {
  236.             result = *(unsigned long *) *aHandle;
  237.             ReleaseResource( aHandle );
  238.         }
  239.     }
  240.     
  241.     return result;
  242. }
  243.  
  244.  
  245.  
  246. static pascal void MyResponse ( NMRecPtr n )
  247. {
  248.     DisposePtr ( (Ptr) n->nmStr );
  249.     NMRemove ( n );
  250.     if ( ! n->nmRefCon )        // true if error was fatal
  251.         DisposePtr ( (Ptr) n );
  252.     else
  253.         n->nmRefCon = 0L;
  254.     
  255.     return;
  256. }
  257.  
  258.  
  259. // Use the Notification manager to display a message.
  260. // Pass true to fFatal if the applcation is to quit afterwards.
  261.  
  262. void    Notify( StringPtr notice, Boolean fFatal )
  263. {
  264.     // remember, no user interface to play with
  265.     NMRecPtr    notePtr;
  266.     OSErr        err;
  267.     
  268.     notePtr = (NMRecPtr) NewPtr ( sizeof ( NMRec ) );
  269.     if ( MemError ( ) )
  270.         return;
  271.     
  272.     notePtr->qType = nmType;            // standard queue type for NM
  273.     notePtr->nmMark = 0;                // background only
  274.     notePtr->nmIcon = 0L;
  275.     notePtr->nmSound = (Handle) -1L;    // use system alert snd
  276.     notePtr->nmStr = NULL;
  277.     notePtr->nmStr = (StringPtr) NewPtr ( sizeof ( Str255 ) );
  278.     BlockMoveData( notice, notePtr->nmStr, notice[0] + 1 );
  279.     notePtr->nmResp = NewNMProc( MyResponse );
  280.     notePtr->nmRefCon = fFatal;
  281.     
  282.     err = NMInstall ( notePtr );
  283.     if ( err == noErr && fFatal )
  284.     {
  285.         while ( notePtr->nmRefCon )
  286.             CheckEventQueue( );
  287.         gQuit = true;
  288.     }
  289.  
  290.     return;
  291. }
  292.